package com.smartleanx.module.hrm.dal.mysql.employee;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.smartleanx.framework.common.pojo.PageParam;
import com.smartleanx.framework.common.pojo.PageResult;
import com.smartleanx.framework.datapermission.core.annotation.DataPermission;
import com.smartleanx.framework.mybatis.core.mapper.BaseMapperX;
import com.smartleanx.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.smartleanx.module.hrm.controller.admin.dingDing.bo.DingAttendanceRecordBo;
import com.smartleanx.module.hrm.controller.admin.employee.vo.*;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.eums.employee.EmployeeStatusEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 员工 Mapper
 *
 * @author tengcj
 */
@Mapper
public interface EmployeeMapper extends BaseMapperX<EmployeeDO> {


    List<EmployeeDO> selectEmployeeList (DingAttendanceRecordBo dingAttendanceRecordBo);
    default PageResult<EmployeeDO> selectPage(EmployeePageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<EmployeeDO>()
                .likeIfPresent(EmployeeDO::getMobile, reqVO.getMobile())
                .likeIfPresent(EmployeeDO::getEmployeeNo, reqVO.getEmployeeNo())
                .inIfPresent(EmployeeDO::getDeptId, reqVO.getDeptIds())
                .likeIfPresent(EmployeeDO::getMobile, reqVO.getMobile())
                .eqIfPresent(EmployeeDO::getPostId, reqVO.getPostId())
                .eqIfPresent(EmployeeDO::getEmploymentForm, reqVO.getEmploymentForm())
                .eqIfPresent(EmployeeDO::getEmploymentType, reqVO.getEmploymentType())
                .inIfPresent(EmployeeDO::getState, reqVO.getState())
                .eqIfPresent(EmployeeDO::getSex, reqVO.getSex())
                .betweenIfPresent(EmployeeDO::getRegularizationTime, reqVO.getRegularizationTime())
                .betweenIfPresent(EmployeeDO::getEntryTime, reqVO.getEntryTime())
                .likeIfPresent(EmployeeDO::getName, reqVO.getName())
                .likeIfPresent(EmployeeDO::getWorkAddress, reqVO.getWorkAddress())
                .inIfPresent(EmployeeDO::getId, reqVO.getId())
                .orderByDesc(EmployeeDO::getId));
    }

    default PageResult<EmployeeDO> selectEmployeePageByIds(EmployeeDashboardPageReqVO pageReqVO) {
        return selectPage(pageReqVO, new LambdaQueryWrapperX<EmployeeDO>()
                .in(EmployeeDO::getId, pageReqVO.getId())
                .orderByDesc(EmployeeDO::getId));
    }

    default PageResult<EmployeeDO> selectEmployeeDeptPage(EmployeeDeptPageReqVo reqVo) {
        return selectPage(reqVo, new LambdaQueryWrapperX<EmployeeDO>()
                .likeIfPresent(EmployeeDO::getName, reqVo.getName())
                .in(EmployeeDO::getDeptId, reqVo.getDeptIdList())
                .ne(EmployeeDO::getState, EmployeeStatusEnum.SEPARATED.getCode())
                .orderByDesc(EmployeeDO::getId));
    }

    /**
     * 根据条件返回员工
     *
     * @param queryRepVo
     * @return
     */
    default List<EmployeeDO> getEmployeeIdsByQuery(EmployeeQueryRepVo queryRepVo) {
        LambdaQueryWrapperX<EmployeeDO> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.likeIfPresent(EmployeeDO::getName, queryRepVo.getEmployeeName());
        wrapperX.eqIfPresent(EmployeeDO::getState, queryRepVo.getEmployeeState());
        wrapperX.eqIfPresent(EmployeeDO::getDeptId, queryRepVo.getDeptId());
        if (Objects.nonNull(queryRepVo.getKeyword())) {
            wrapperX.and(q -> q.like(EmployeeDO::getEmployeeNo, queryRepVo.getKeyword()).or().like(EmployeeDO::getName, queryRepVo.getKeyword()));
        }
        return selectList(wrapperX);
    }


    /**
     * 进行逻辑删除并更新删除时间
     *
     * @param id
     * @param deletedTime
     * @return
     */
    @Update("UPDATE hrm_employee SET deleted = 1, deleted_time = #{deletedTime} where id = #{id} and deleted = 0")
    int updateToDeleteById(@Param("id") Long id, @Param("deletedTime") Long deletedTime);

    default int updateEmployeeInfo(EmployeeDO employeeDO) {
        return update(new LambdaUpdateWrapper<EmployeeDO>()
                .eq(EmployeeDO::getId, employeeDO.getId())
                .set(employeeDO.getName() != null, EmployeeDO::getName, employeeDO.getName())
                .set(EmployeeDO::getMobile, employeeDO.getMobile())
                .set(EmployeeDO::getIdType, employeeDO.getIdType())
                .set(EmployeeDO::getIdNumber, employeeDO.getIdNumber())
                .set(EmployeeDO::getSex, employeeDO.getSex())
                .set(EmployeeDO::getDateOfBirth, employeeDO.getDateOfBirth())
                .set(EmployeeDO::getBirthday, employeeDO.getBirthday())
                .set(EmployeeDO::getBirthdayType, employeeDO.getBirthdayType())
                .set(EmployeeDO::getMarried, employeeDO.getMarried())
                .set(EmployeeDO::getFertilized, employeeDO.getFertilized())
                .set(EmployeeDO::getHealthStatus, employeeDO.getHealthStatus())
                .set(EmployeeDO::getHighestEducation, employeeDO.getHighestEducation())
                .set(EmployeeDO::getResidenceAddress, employeeDO.getResidenceAddress())
                .set(EmployeeDO::getPersonalEmail, employeeDO.getPersonalEmail())
                .set(EmployeeDO::getEmergencyContactNumber, employeeDO.getEmergencyContactNumber())
                .set(EmployeeDO::getEmergencyContact, employeeDO.getEmergencyContact())
                .set(EmployeeDO::getCurrentAddress, employeeDO.getCurrentAddress())
                .set(EmployeeDO::getCardNumber, employeeDO.getCardNumber())
                .set(EmployeeDO::getBankName, employeeDO.getBankName())
                .set(EmployeeDO::getOpeningBank, employeeDO.getOpeningBank())
        );
    }

    default int updateEmployeeDept(EmployeeDO employeeDO) {
        return update(new LambdaUpdateWrapper<EmployeeDO>()
                .eq(EmployeeDO::getId, employeeDO.getId())
                .set(EmployeeDO::getEntryTime, employeeDO.getEntryTime())
                .set(EmployeeDO::getEmployeeNo, employeeDO.getEmployeeNo())
                .set(EmployeeDO::getDeptId, employeeDO.getDeptId())
                .set(EmployeeDO::getPostId, employeeDO.getPostId())
                .set(EmployeeDO::getPostLevelId, employeeDO.getPostLevelId())
                .set(EmployeeDO::getLeaderId, employeeDO.getLeaderId())
                .set(EmployeeDO::getEmploymentForm, employeeDO.getEmploymentForm())
                .set(EmployeeDO::getProbationPeriod, employeeDO.getProbationPeriod())
                .set(EmployeeDO::getEmploymentType, employeeDO.getEmploymentType())
                .set(EmployeeDO::getWorkAddress, employeeDO.getWorkAddress())
                .set(EmployeeDO::getRegularizationTime, employeeDO.getRegularizationTime())
                .set(EmployeeDO::getState, employeeDO.getState())
        );
    }

    default List<EmployeeDO> selectListByDeptId(Collection<Long> deptIdList, Integer status) {
        return selectList(new LambdaQueryWrapperX<EmployeeDO>()
                .in(EmployeeDO::getDeptId, deptIdList)
                .eqIfPresent(EmployeeDO::getState, status)
        );
    }

    default List<EmployeeDO> selectListByDeptLevelId(Long postLevelId) {
        return selectList(new LambdaQueryWrapper<EmployeeDO>()
                .eq(EmployeeDO::getPostLevelId, postLevelId));
    }

    default List<EmployeeDO> selectListByPostId(Long postId) {
        return selectList(EmployeeDO::getPostId, postId);
    }

    default EmployeeDO selectByEmployeeNo(String employeeNo) {
        return selectOne(EmployeeDO::getEmployeeNo, employeeNo);
    }

    default EmployeeDO selectEmployeeByNameAndPhone(String name,String phone) {
        return selectOne(EmployeeDO::getName, name,EmployeeDO::getMobile,phone);
    }

    default List<EmployeeDO> selectListByEmployeeNoS(Collection<String> employeeNos) {
        return selectList(new LambdaQueryWrapper<EmployeeDO>()
                .in(EmployeeDO::getEmployeeNo, employeeNos));
    }

    default EmployeeDO selectByUserId(Long userId) {
        return selectOne(EmployeeDO::getUserId, userId);
    }

    @DataPermission(enable = false) //是否开启权限
    default EmployeeDO selectEmpById(Long empid) {
        return selectOne(EmployeeDO::getId, empid);
    }

    default List<EmployeeDO> selectListByUserIds(Set<Long> userIds) {
        return selectList(EmployeeDO::getUserId, userIds);
    }

    default int deleteEmployeeUser(Long employeeId) {
        return update(new LambdaUpdateWrapper<EmployeeDO>()
                .set(EmployeeDO::getUserId, null)
                .eq(EmployeeDO::getId, employeeId)
        );
    }

    // @Select("SELECT * FROM hrm_employee WHERE user_id = #{userId}")
    // EmployeeDO selectEmployeeByUserId(@Param("userId") Long userId);

    default List<EmployeeDO> getEmployeeList(String name) {
        return selectList(new LambdaQueryWrapperX<EmployeeDO>()
                .likeIfPresent(EmployeeDO::getName, name));
    }

    default List<EmployeeDO> getEmployeeList() {
        return selectList(new LambdaQueryWrapperX<EmployeeDO>());
    }

    default List<EmployeeDO> selectEmpSimpleList(EmployeeLikeQueryReqVO queryReqVO) {
        LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(queryReqVO.getLikeStr())) {
            queryWrapper.like(EmployeeDO::getName, queryReqVO.getLikeStr());
            queryWrapper.or().like(EmployeeDO::getEmployeeNo, queryReqVO.getLikeStr());
        }
        PageResult<EmployeeDO> result = selectPage(new PageParam().setPageNo(1).setPageSize(queryReqVO.getLimit()), queryWrapper);
        return result.getList();
    }

    default List<EmployeeDO> getLoginEmpList(EmployeeLikeQueryReqVO queryReqVO) {
        LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(queryReqVO.getLikeStr())) {
            queryWrapper.like(EmployeeDO::getName, queryReqVO.getLikeStr());
            queryWrapper.or().like(EmployeeDO::getEmployeeNo, queryReqVO.getLikeStr());
        }
        queryWrapper.isNotNull(EmployeeDO::getUserId);
        PageResult<EmployeeDO> result = selectPage(new PageParam().setPageNo(1).setPageSize(queryReqVO.getLimit()), queryWrapper);
        return result.getList();
    }

}
